package com.it.sun.redismq.handler;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.json.JSONUtil;
import com.it.sun.redismq.vo.Message;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisTemplate;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Set;

/**
 * @ClassName com.it.sun.springboot.course.invoke.AbstractMessageHandler
 * @Author sun
 * @Date 2021/1/28 10:21
 * @Version V1.0
 * Description  <请输入一句话描述该类功能>
 * Copyright (C) xxxx  since 2021/1/28
 */
@Slf4j
public abstract class AbstractMessageHandler implements ApplicationContextAware {

    protected ApplicationContext applicationContext;

    protected RedisTemplate redisTemplate;

    protected void invokeMethod(Method method, Message message, Object bean) {
        try {
            method.invoke (bean, message);
        } catch (IllegalAccessException e) {
            e.printStackTrace ();
        } catch (InvocationTargetException e) {
            e.printStackTrace ();
        }
    }

    protected Message getMessage(byte[] bytes) {
        String s = new String (bytes, CharsetUtil.CHARSET_UTF_8);
        return JSONUtil.toBean (s, Message.class);
    }

    public AbstractMessageHandler(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    protected RedisConnection getConnection() {
        RedisConnection connection = redisTemplate.getRequiredConnectionFactory ().getConnection ();
        return connection;
    }

    public abstract void invokeMessage(Method method);

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    protected void consumer(Method method, Set<String> consumers, Object bean, byte[] message) {
        Message msg = getMessage (message);
        if (consumers.add (msg.getId ())) {
            invokeMethod (method, msg, bean);
        } else {
            log.error ("has consumed message {}", msg);
        }
    }
}
